package com.taotao.service.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import com.alibaba.fastjson.JSONObject;
import com.taotao.common.wxpay.WXPayUtil;
import com.taotao.mapper.*;
import com.taotao.pojo.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import com.taotao.common.enums.OrderStatus;
import com.taotao.common.enums.TemplateDesc;
import com.taotao.common.pojo.BaseResult;
import com.taotao.common.utils.Constants;
import com.taotao.common.utils.DateUtil;
import com.taotao.common.wxpay.MyWXConfig;
import com.taotao.common.wxpay.WXPay;
import com.taotao.service.ChargeService;
import com.taotao.service.OperateLogService;
import com.taotao.service.ParamService;
import com.taotao.service.WechatPayService;
import com.taotao.service.WechatService;

@Service
public class WechatPayServiceImpl implements WechatPayService {

	private static final Logger logger = LoggerFactory.getLogger(WechatPayServiceImpl.class);
	@Autowired
	EyMemberMapper eyMemberMapper;
	@Autowired
	EyGoodsMapper eyGoodsMapper;
	@Autowired
	OperateLogService operateLogService;
	@Autowired
	EyOrderMapper eyOrderMapper;
	@Autowired
	EyOrderWxpayMapper eyOrderWxpayMapper;
	@Autowired
	EyTransferMapper eyTransferMapper;
	@Autowired
	ParamService paramService;
	@Autowired
	ChargeService chargeService;
	@Autowired
	WechatService wechatService;
	@Autowired
	EyServiceMapper eyServiceMapper;
	@Autowired
	EyOfficialAccountsMapper eyOfficialAccountsMapper;
	
	public static String accessToken_xcx_prefix = "accessToken_xcx";
	public static String accessToken_gzh_prefix = "accessToken_gzh";
	public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	  
	
	BaseResult baseResult = new BaseResult();

	/**
	 * 关闭订单
	 */
	@Override
	public Map<String, Object> closeOrder(Map<String, String> map) {
		try {
			String out_trade_no=map.get("out_trade_no");
			String nonce_str=UUID.randomUUID().toString();
			String sign="";
			MyWXConfig.init(ParamServiceImpl.getResourceParam("apiclient_cert_path"));
			MyWXConfig config = new MyWXConfig();
	        WXPay wxpay = new WXPay(config);
	        Map<String, String> data = new HashMap<String, String>();
	        data.put("nonce_str", nonce_str);
	        data.put("sign", sign);
	        data.put("out_trade_no", out_trade_no);
		} catch (Exception e) {
			e.printStackTrace();
			
		}
		return null;
	}
	
	
	/**
	 * 查询订单
	 */
	@Override
	public Map<String, Object> orderQuery(Map<String, String> map) {
		try {
			String out_trade_no=map.get("out_trade_no");
			String nonce_str=UUID.randomUUID().toString();
			String sign="";
			MyWXConfig.init(ParamServiceImpl.getResourceParam("apiclient_cert_path"));
			MyWXConfig config = new MyWXConfig();
	        WXPay wxpay = new WXPay(config);
	        Map<String, String> data = new HashMap<String, String>();
	        data.put("out_trade_no", out_trade_no);
	            Map<String, String> resp = wxpay.orderQuery(data);
	            System.out.println("返回-->"+resp);
	            return baseResult.getSuccMap(resp);
	        } catch (Exception e) {
	            e.printStackTrace();
	            return baseResult.getErrorMap("网络繁忙，请稍后再试");
	        }
	}

	/**
	 * 微信浏览器内调用JSAPI支付
	 */
	@Override
	public Map<String, Object> createJSAPI(Map<String, String> map) {
		try {

			Map<String, Object> response = this.unifiedOrder(map);
			Map<String, String> unifiedMap = (Map)response.get("data");

			String appid = (String) unifiedMap.get("appid");
			String prepay_id = (String) unifiedMap.get("prepay_id");
			String nonce_str = (String) unifiedMap.get("nonce_str");
			Map<String, String> mapParam = new HashMap();
			mapParam.put("appId", appid);
			mapParam.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
			mapParam.put("nonceStr", nonce_str.trim());
			mapParam.put("package", "prepay_id="+prepay_id.trim());
			mapParam.put("signType", "MD5");
			//二次签名，需要再次将参数(不包括paySign)MD5签名
			MyWXConfig config = new MyWXConfig();
			String paySign = WXPayUtil.generateSignature(mapParam, config.getKey());
			mapParam.put("paySign", paySign);
			System.out.println("createJSAPI-->"+ mapParam.toString());
			return baseResult.getSuccMap(mapParam);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}


	/**
	 * 统一下单接口
	 */
	@Override
	public Map<String, Object> unifiedOrder(Map<String, String> map) {
        try {
        	 String out_trade_no=map.get("out_trade_no");
        	 String total_fee=map.get("total_fee");
        	 String openid=map.get("openid");
     		 String notify_url = paramService.getParam("wxPayNotify");
        	 
     		 MyWXConfig.init(ParamServiceImpl.getResourceParam("apiclient_cert_path"));
        	 MyWXConfig config = new MyWXConfig();
             WXPay wxpay = new WXPay(config);
             Map<String, String> data = new HashMap<String, String>();
             data.put("body", "JSAPI支付测试");
             data.put("out_trade_no",out_trade_no);
             data.put("fee_type", "CNY");
             data.put("total_fee",total_fee);
             data.put("notify_url",notify_url);
             data.put("trade_type", "JSAPI"); 
             data.put("openid", openid);

			 System.out.println("unifiedOrder request-->"+data.toString());
             Map<String, String> resp = wxpay.unifiedOrder(data);
			System.out.println("unifiedOrder response-->"+resp.toString());

             return baseResult.getSuccMap(resp);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
	}

	/**
	 * 申请退款
	 */
	@Override
	public Map<String, Object> refund(Map<String, String> map) {
        try {
        	 String memberId=map.get("memberId");
        	 String orderId=map.get("orderId");
        		
        	 EyOrder order = eyOrderMapper.selectByPrimaryKey(Integer.parseInt(orderId));
    		 if(order==null){
				return baseResult.getErrorMap("退款订单不存在,orderId:"+orderId);
			 }
    		 
    		 EyOrderWxpayExample orderWxpayExample = new EyOrderWxpayExample();
 			 com.taotao.pojo.EyOrderWxpayExample.Criteria criteriaOrder = orderWxpayExample.createCriteria();
 			 criteriaOrder.andOutTradeNoEqualTo(order.getOutTradeNo());
 			 List<EyOrderWxpay> orderWxpayList = eyOrderWxpayMapper.selectByExample(orderWxpayExample);
 			 EyOrderWxpay eyOrderWxpay = orderWxpayList.get(0);
        	 
        	 String out_trade_no=order.getOutTradeNo();
        	 String out_refund_no=out_trade_no+"_refund";
        	 String total_fee=eyOrderWxpay.getTotalFee();
        	 String refund_fee=total_fee;
        	 
     		 MyWXConfig.init(ParamServiceImpl.getResourceParam("apiclient_cert_path"));
        	 MyWXConfig config = new MyWXConfig();
             WXPay wxpay = new WXPay(config);
             Map<String, String> data = new HashMap<String, String>();
             data.put("out_trade_no",out_trade_no);
             data.put("out_refund_no",out_refund_no);
             data.put("fee_type", "CNY");
             data.put("total_fee",total_fee);
             data.put("refund_fee",refund_fee);
             
             Map<String, String> resp = wxpay.refund(data);
             System.out.println(resp);
             if(Constants.success.equals(resp.get("result_code")) && Constants.success.equals(resp.get("result_code"))){ //退款成功
            	 order.setStatus(OrderStatus.orderStatus_5.getCode()); //已退款
            	 order.setUpdateTime(DateUtil.getDateAndTime());
            	 eyOrderMapper.updateByPrimaryKey(order);
            	 return baseResult.getSuccMap();
             }else{
            	 return baseResult.getErrorMap("Fail");
             }
        } catch (Exception e) {
            e.printStackTrace();
            return baseResult.getErrorMap("网络繁忙");
        }
	}



	/**
	 * 结果通知
	 */
	@Override
	public Map<String, Object> wxPayNotify(Map<String, String> map,EyOrder eyOrder) {
		try {
			String out_trade_no=map.get("out_trade_no");
			String transaction_id=map.get("transaction_id");
			String nonce_str=map.get("nonce_str");
			String bank_type=map.get("bank_type");
			String openid=map.get("openid");
			String sign=map.get("sign");
			String fee_type=map.get("fee_type");
			String mch_id=map.get("mch_id");
			String cash_fee=map.get("cash_fee");
			String appid=map.get("appid");
			String total_fee=map.get("total_fee");
			String trade_type=map.get("trade_type");
			String result_code=map.get("result_code");
			String time_end=map.get("time_end");
			String is_subscribe=map.get("is_subscribe");
			String return_code=map.get("return_code");
			EyOrderWxpay wxpay=new EyOrderWxpay();
			
			boolean insert=true;
			EyOrderWxpayExample example = new EyOrderWxpayExample();
			com.taotao.pojo.EyOrderWxpayExample.Criteria criteria = example.createCriteria();
			criteria.andOutTradeNoEqualTo(out_trade_no);
			List<EyOrderWxpay> list= eyOrderWxpayMapper.selectByExample(example);
			if(list!=null && list.size()>0){
				wxpay = list.get(0);
				insert=false;
			}
			
			wxpay.setTransactionId(transaction_id);
			wxpay.setBankType(bank_type);
			wxpay.setOpenid(openid);
			wxpay.setSign(sign);
			wxpay.setMchId(mch_id);
			wxpay.setCashFee(cash_fee);
			wxpay.setOutTradeNo(out_trade_no);
			wxpay.setNonceStr(nonce_str);
			wxpay.setFeeType(fee_type);
			wxpay.setTimeEnd(time_end);
			wxpay.setAppid(appid);
			wxpay.setTotalFee(total_fee);
			wxpay.setTradeType(trade_type);
			wxpay.setResultCode(result_code);
			wxpay.setIsSubscribe(is_subscribe);
			wxpay.setResultCode(return_code);
			wxpay.setUpdateTime(DateUtil.getDateAndTime());
			
			if(insert){
				wxpay.setCreateTime(DateUtil.getDateAndTime());
				eyOrderWxpayMapper.insert(wxpay);
			}else{
				eyOrderWxpayMapper.updateByPrimaryKey(wxpay);
			}
		
			//修改订单状态
			eyOrder.setStatus(OrderStatus.orderStatus_2.getCode());//付款成功，服务中
			eyOrder.setUpdateTime(DateUtil.getDateAndTime());
			eyOrderMapper.updateByPrimaryKey(eyOrder);

			if(eyOrder.getTransferId()!=null){
				Integer transferId=eyOrder.getTransferId();
				EyTransfer transfer = eyTransferMapper.selectByPrimaryKey(transferId);
				transfer.setUpdateTime(DateUtil.getDateAndTime());
				transfer.setStatus(Constants.num_2); //1待付款 2已付款
				eyTransferMapper.updateByPrimaryKeySelective(transfer);
			}
			
			if(Constants.charge.equals(eyOrder.getModeType())){ //充值类 支付成功之后插入charge表
				Map<String,String> chargeMap=new HashMap<String,String>();
				chargeMap.put("memberId", String.valueOf(eyOrder.getMemberId()));
				chargeMap.put("priceTotal", eyOrder.getPriceTotal());
				chargeMap.put("priceDiscount", eyOrder.getPriceDiscount());
				chargeMap.put("pricePay", eyOrder.getPricePay());
				chargeMap.put("chargeDesc", "充值成功");
				chargeService.chargeAdd(map);
			}else if(Constants.goods.equals(eyOrder.getModeType())){ //goods类，发送模板消息给卖家
				EyGoods goods = eyGoodsMapper.selectByPrimaryKey(eyOrder.getGoodsId());
        	    HashMap<String,String> m=new HashMap<String,String>();
				m.put("sender", eyOrder.getMemberId().toString()); //发送者 买方
                m.put("receiver",goods.getMemberId().toString()); //接受者 卖方
                m.put("sessionKey","");
                m.put("messageId", "");
                m.put("content", "Please deliver the goods as soon as possible");
                m.put("orderId", String.valueOf(eyOrder.getId()));
                m.put("templateId", TemplateDesc.Template_3.getCode()); //购买成功，提醒卖家发货
                wechatService.sendMsg(m);
			}else if(Constants.service.equals(eyOrder.getModeType())) { //service，发送修改service 状态为2已付款
				EyService service = eyServiceMapper.selectByPrimaryKey(eyOrder.getServiceId());
				if(service!=null){
					service.setStatus(OrderStatus.orderStatus_2.getCode()); //付款成功，服务中
					service.setUpdateTime(DateUtil.getDateAndTime());
					eyServiceMapper.updateByPrimaryKeySelective(service);
				}
			}
			return baseResult.getSuccMap();
		} catch (Exception e) {
			e.printStackTrace();
			return baseResult.getErrorMap("");
		}
		
	}

	public JSONObject getCheekServiceMessageJson(EyOrder eyOrder) {
		JSONObject messageJson=new JSONObject();
		EyService service = eyServiceMapper.selectByPrimaryKey(eyOrder.getServiceId());
		String sender=paramService.getParam("admin_member_id");
		messageJson.put("content", "Please check your order");
		messageJson.put("sender",sender);
		messageJson.put("receiver", service.getMemberId());
		messageJson.put("modeType", Constants.service);
		messageJson.put("msgType", "6");  //服务类的确认订单
		messageJson.put("serviceName", service.getServiceName());
		messageJson.put("outTradeNo", eyOrder.getOutTradeNo());
		messageJson.put("sessionKey", "");
		messageJson.put("id", service.getId());
		messageJson.put("orderId", eyOrder.getId());
		return messageJson;
	}

	public JSONObject getCheekGoodsMessageJson(EyOrder eyOrder) {
		JSONObject messageJson=new JSONObject();
		EyGoods goods = eyGoodsMapper.selectByPrimaryKey(eyOrder.getGoodsId());
		messageJson.put("content", "Please check your order");
		messageJson.put("sender",goods.getMemberId());
		messageJson.put("receiver", eyOrder.getMemberId());
		messageJson.put("modeType", Constants.goods);
		messageJson.put("msgType", "5");  //goods类的确认订单
		messageJson.put("serviceName", "");
		messageJson.put("outTradeNo", eyOrder.getOutTradeNo());
		messageJson.put("sessionKey", "");
		messageJson.put("id", goods.getId());
		messageJson.put("orderId", eyOrder.getId());
		return messageJson;
	}

}
